package com.shareyi.wox.context;

import java.util.HashMap;
import java.util.Map;

import com.shareyi.wox.core.ActionInvocation;
import com.shareyi.simpleserver.core.HttpRequest;
import com.shareyi.simpleserver.core.HttpResponse;



public class ActionContext {
	
	 public static ThreadLocal<ActionContext> actionContext;
	    
	 static{
		 actionContext=new ThreadLocal<ActionContext>();
	    }
	    
	 
	 
	  /**
	     * Constant for the name of the action being executed.
	     */
    public static final String ACTION_NAME = "com.shareyi.wox.ActionContext.name";
    public static final String HTTP_REQUEST = "com.shareyi.wox.ActionContext.request";
    public static final String HTTP_RESPONSE = "com.shareyi.wox.ActionContext.response";
    public static final String PARAMETERS = "com.shareyi.wox.ActionContext.parameters";
	private static final String ACTION_INVOCATION =  "com.shareyi.wox.ActionContext.actionInvocation";
	private static final String VALUE_CONTEXT =  "com.shareyi.wox.ActionContext.valueContext";
	
    Map<String, Object> context;
    private ValueContext valueContext;
	 
	HttpRequest request;
	HttpResponse response;
//  ServletContext context;
  
	public ActionContext(HttpRequest request, HttpResponse response) {
		context=new HashMap<String, Object>();
		this.request = request;
		this.response = response;
		context.put(HTTP_REQUEST, request);
		context.put(HTTP_RESPONSE, response);
	}
	

	public ActionContext(HttpRequest request, HttpResponse response,ValueContext valueContext) {
		context=new HashMap<String, Object>();
		this.request = request;
		this.response = response;
		this.setValueContext(valueContext);
		
		context.put(VALUE_CONTEXT, valueContext);
		context.put(HTTP_REQUEST, request);
		context.put(HTTP_RESPONSE, response);
	}



	public HttpRequest getRequest() {
		return request;
	}
	public void setRequest(HttpRequest request) {
		this.request = request;
	}
	public HttpResponse getResponse() {
		return response;
	}
	public void setResponse(HttpResponse response) {
		this.response = response;
	}
	  

    /**
     * Returns a value that is stored in the current ActionContext by doing a lookup using the value's key.
     *
     * @param key the key used to find the value.
     * @return the value that was found using the key or <tt>null</tt> if the key was not found.
     */
    public Object get(String key) {
        return context.get(key);
    }

    /**
     * Stores a value in the current ActionContext. The value can be looked up using the key.
     *
     * @param key   the key of the value.
     * @param value the value to be stored.
     */
    public void put(String key, Object value) {
        context.put(key, value);
    }
  
    /**
     * Sets the action invocation (the execution state).
     *
     * @param actionInvocation the action execution state.
     */
    public void setActionInvocation(ActionInvocation actionInvocation) {
        put(ACTION_INVOCATION, actionInvocation);
    }

    /**
     * Gets the action invocation (the execution state).
     *
     * @return the action invocation (the execution state).
     */
    public ActionInvocation getActionInvocation() {
        return (ActionInvocation) get(ACTION_INVOCATION);
    }
    
    /**
     * Sets the action context for the current thread.
     *
     * @param context the action context.
     */
    public static void setContext(ActionContext context) {
        actionContext.set(context);
    }

    /**
     * Returns the ActionContext specific to the current thread.
     *
     * @return the ActionContext for the current thread, is never <tt>null</tt>.
     */
    public static ActionContext getContext() {
        return (ActionContext) actionContext.get();
    }

    /**
     * Sets the action's context map.
     *
     * @param contextMap the context map.
     */
    public void setContextMap(Map<String, Object> contextMap) {
        getContext().context = contextMap;
    }

    /**
     * Gets the context map.
     *
     * @return the context map.
     */
    public Map<String, Object> getContextMap() {
        return context;
    }
    
    
    /**
     * Sets the name of the current Action in the ActionContext.
     *
     * @param name the name of the current action.
     */
    public void setName(String name) {
        put(ACTION_NAME, name);
    }

    /**
     * Gets the name of the current Action.
     *
     * @return the name of the current action.
     */
    public String getName() {
        return (String) get(ACTION_NAME);
    }

    /**
     * Sets the action parameters.
     *
     * @param parameters the parameters for the current action.
     */
    public void setParameters(Map<String, Object> parameters) {
        put(PARAMETERS, parameters);
    }

    /**
     * Returns a Map of the HttpServletRequest parameters when in a servlet environment or a generic Map of
     * parameters otherwise.
     *
     * @return a Map of HttpServletRequest parameters or a multipart map when in a servlet environment, or a
     *         generic Map of parameters otherwise.
     */
    public Map<String, Object> getParameters() {
        return (Map<String, Object>) get(PARAMETERS);
    }


	public ValueContext getValueContext() {
		return valueContext;
	}


	public void setValueContext(ValueContext valueContext) {
		this.valueContext = valueContext;
	}


}
